#include <thread>
#include "DiskManager.h"
#include "Protocol/ProtocolApi.h"
#include "DiskController.h"
#include "log.h"



using namespace Protocol;



DiskManager::Ptr DiskManager::Instance(){
    static auto ptr = std::make_shared<DiskManager>();
    return ptr;
}


DiskManager::DiskManager(){
    RegistRPC();
    //diskChangeEvent();
}

DiskManager::~DiskManager(){

}

void DiskManager::RegistRPC(){
    IProtocolInterface::GetInstance()->AuditoryworksRegistRequestRpc("getDiskStatus", 
        [this](const Json::Value& req_params, Json::Value& res_result, std::string& errinfo){
            return getDiskStatus(req_params, res_result, errinfo);
        });
}


bool DiskManager::getDiskStatus(const Json::Value& req_params, Json::Value& res_result, std::string& errinfo){
    //这里的获取磁盘信息需要管理U盘和板载的Flash两块空间，U盘优先级高于板载
    //1、查看当前U盘是否挂载，如果挂载直接获取U盘的空间信息返回
    //2、查看当前U盘是否挂载，如果没有挂载直接获取Flash的空间信息返回
    unsigned long long usedSpace = 0;
    unsigned long long totalSpace = 0;
    std::string path;
    if(!DiskController::instance()->setRealTimeRootPath()){
        LOG_PrintError("faild get root path\n");
        return false;
    }
    DiskController::instance()->getRealTimeRootPath(path);
    DiskController::instance()->getDiskSpaceInfo(path, usedSpace, totalSpace);
    res_result["d"]["result"]["UsedDiskSpace"] = usedSpace;
    res_result["d"]["result"]["TotalDiskSpace"] = totalSpace;
    return true;
}


bool DiskManager::diskChangeEvent(){
    //这个函数用于U盘热插拔或者U盘空间发生变化时将信息异步通知个给Web
    //对于U盘空间大小改变的通知可以封装一个类专门用于U盘空间操作，并且将通知当作一个回调在每次改变空间时做通知
    //可以拿一个成员变量用于记录当前使用空间大小，每次通知时对比本次获取的大小和成员变量，不一样才异步通知

    auto lamda = [this](){
        while(true){
            sleep(5);
            // 创建 Json::Value 对象并使用字符串进行初始化
            Json::Value root;
            Json::Reader reader;
            bool parsingSuccessful = reader.parse(m_eventDiskInfo, root);

            if (!parsingSuccessful) {
                LOG_PrintError("reeor parse : %s\n", m_eventDiskInfo.c_str());
                break;
            }

            unsigned long long usedSpace = 0;
            unsigned long long totalSpace = 0;
            std::string path;

            if(!DiskController::instance()->setRealTimeRootPath()){
                LOG_PrintError("faild get root path\n");
                continue;
            }
            DiskController::instance()->getRealTimeRootPath(path);
            DiskController::instance()->getDiskSpaceInfo(path, usedSpace, totalSpace);
            root["d"]["data"]["UsedDiskSpace"] = usedSpace;
            root["d"]["data"]["TotalDiskSpace"] = totalSpace;

            if(m_eventDiskInfo != root.toStyledString()){
                m_eventDiskInfo = root.toStyledString();
                IProtocolInterface::GetInstance()->AuditoryworksBroadcastEvent("EventUpdateDeviceList", root);    
            }
        }
    };

    std::thread diskReport(lamda);
	// Gets the underlying pthread_t handle
    pthread_t pthreadHandle = diskReport.native_handle();
    // set thread name
    pthread_setname_np(pthreadHandle, "disk_report");
	diskReport.detach();
    
    return true;
}